/*
 =============================================================================
 FILE...............: FlightSearch.java
 COMMENTS...........: Flight search window on which the user specifies the
 					  criteria for flight search, namely origin airport/city,
 					  target airport/city, and departure and arrival dates.
 =============================================================================
 AUTHOR(S)..........: Everton Ranielly de Sousa Cavalcante
 					  Department of Informatics and Applied Mathematics
 					  Federal University of Rio Grande do Norte
 LAST MODIFICATION..: September 15th, 2012
 ============================================================================= 					  
*/


/* ========================================================================= */
/* PACKAGES			                                                         */
/* ------------------------------------------------------------------------- */
package test.gui;


/* ========================================================================= */
/* IMPORTS			                                                         */
/* ------------------------------------------------------------------------- */
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.text.MaskFormatter;

import org.jdesktop.layout.GroupLayout;
import org.jdesktop.layout.LayoutStyle;

import test.control.AirportController;


/* ========================================================================= */
/* CLASS FlightSearch                                                        */
/* ------------------------------------------------------------------------- */
/**
 * Flight search window on which the user specifies the criteria for flight 
 * search, namely origin airport/city, target airport/city, and departure and 
 * arrival dates
 * @author Everton Cavalcante
 */
@SuppressWarnings("serial")
public class FlightSearch extends JFrame 
{
	// Variables declaration
	private JPanel jPanel1;
	
	private JLabel jLabel1;
	private JComboBox jComboBox1;
	
	private JLabel jLabel2;
	private JComboBox jComboBox2;
	
	private JLabel jLabel3;
	private JTextField jTextField1;
	
	private JLabel jLabel4;
	private JTextField jTextField2;
	
	private JButton jButton1;
	private JButton jButton2;
	
	
	// Member variables
	private AirportController ac = new AirportController();
	public String from = "";
	public String to = "";
	public String departure = "";
	public String arrival = "";
	
	public Object lock = new Object();		// Lock synchronization object
	
	
	/** Creates new window */
	public FlightSearch()
	{ 
		initComponents();
		this.setVisible(true);
	}


	/** Initializes GUI components */
	private void initComponents() 
	{
		try 
		{
			// Set the Nimbus look and feel
            LookAndFeelInfo[] installedLookAndFeels = UIManager.getInstalledLookAndFeels();
            for (int idx = 0; idx < installedLookAndFeels.length; idx++)
            {
                if ("Nimbus".equals(installedLookAndFeels[idx].getName())) 
                {
                    UIManager.setLookAndFeel(installedLookAndFeels[idx].getClassName());
                    break;
                }
            }
        }
		catch (ClassNotFoundException ex) 
		{ Logger.getLogger(FlightSearch.class.getName()).log(Level.SEVERE, null, ex); } 
		catch (InstantiationException ex) 
		{ Logger.getLogger(FlightSearch.class.getName()).log(Level.SEVERE, null, ex); } 
		catch (IllegalAccessException ex) 
        { java.util.logging.Logger.getLogger(FlightSearch.class.getName()).log(Level.SEVERE, null, ex); }
		catch (javax.swing.UnsupportedLookAndFeelException ex) 
        { java.util.logging.Logger.getLogger(FlightSearch.class.getName()).log(Level.SEVERE, null, ex); }
		
		
		// Mask formatter for text field
		try 
		{ 
			MaskFormatter format_textField = new MaskFormatter("##/##/####");	// Date mask
			format_textField.setPlaceholderCharacter(' ');						// Place holder character
			format_textField.setValidCharacters("0123456789");					// Accepts only numbers
		
			// Initializes GUI components
			jPanel1 = new JPanel();
			
			jLabel1 = new JLabel();
			jComboBox1 = new JComboBox();
			
			jLabel2 = new JLabel();
			jComboBox2 = new JComboBox();
			
			jLabel3 = new JLabel();
			jTextField1 = new JFormattedTextField(format_textField);
			
			jLabel4 = new JLabel();
			jTextField2 = new JFormattedTextField(format_textField);
			
			jButton1 = new JButton();
			jButton2 = new JButton();
			
			setDefaultCloseOperation(javax.swing.WindowConstants.HIDE_ON_CLOSE);
			setTitle("Flight Booking");
		}
		
		catch (ParseException e) 
		{ e.printStackTrace(); }
		
		jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder(" Flight Search "));
		
		jLabel1.setText("From:");
		jComboBox1.setModel(new DefaultComboBoxModel(ac.getAirports()));
		
		jLabel2.setText("To:");
		jComboBox2.setModel(new DefaultComboBoxModel(ac.getAirports()));
		
		jLabel3.setText("Departure:");
		jLabel4.setText("Arrival:");
		
		GroupLayout jPanel1Layout = new GroupLayout(jPanel1);
		jPanel1.setLayout(jPanel1Layout);
		jPanel1Layout.setHorizontalGroup(
	            jPanel1Layout.createParallelGroup(GroupLayout.LEADING)
	            .add(jPanel1Layout.createSequentialGroup()
	                .add(jPanel1Layout.createParallelGroup(GroupLayout.LEADING)
	                    .add(jPanel1Layout.createSequentialGroup()
	                        .add(69, 69, 69)
	                        .add(jPanel1Layout.createParallelGroup(GroupLayout.LEADING)
	                            .add(GroupLayout.TRAILING, jLabel2)
	                            .add(GroupLayout.TRAILING, jLabel1))
	                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
	                        .add(jPanel1Layout.createParallelGroup(GroupLayout.LEADING)
	                            .add(jComboBox1, 0, 307, Short.MAX_VALUE)
	                            .add(jComboBox2, 0, 307, Short.MAX_VALUE)))
	                    .add(GroupLayout.TRAILING, jPanel1Layout.createSequentialGroup()
	                        .addContainerGap()
	                        .add(jLabel3)
	                        .addPreferredGap(LayoutStyle.RELATED)
	                        .add(jTextField1, GroupLayout.DEFAULT_SIZE, 142, Short.MAX_VALUE)
	                        .add(21, 21, 21)
	                        .add(jLabel4)
	                        .addPreferredGap(LayoutStyle.RELATED)
	                        .add(jTextField2, GroupLayout.DEFAULT_SIZE, 142, Short.MAX_VALUE)))
	                .addContainerGap())
	    );
		
		jPanel1Layout.setVerticalGroup(
	            jPanel1Layout.createParallelGroup(GroupLayout.LEADING)
	            .add(jPanel1Layout.createSequentialGroup()
	                .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
	                .add(jPanel1Layout.createParallelGroup(GroupLayout.BASELINE)
	                    .add(jLabel1)
	                    .add(jComboBox1, GroupLayout.PREFERRED_SIZE, 
	                    	GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
	                .addPreferredGap(LayoutStyle.RELATED)
	                .add(jPanel1Layout.createParallelGroup(GroupLayout.BASELINE)
	                    .add(jLabel2)
	                    .add(jComboBox2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
	                .add(18, 18, 18)
	                .add(jPanel1Layout.createParallelGroup(GroupLayout.BASELINE)
	                    .add(jLabel3)
	                    .add(jTextField1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
	                    .add(jTextField2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
	                    .add(jLabel4)))
	    );
		
		jButton1.setText("Cancel");
		jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) 
            { jButton1ActionPerformed(evt); }
		});
		
        jButton2.setText("OK");
        jButton2.addActionListener(new java.awt.event.ActionListener() {
        	public void actionPerformed(java.awt.event.ActionEvent evt) 
        	{ 
        		synchronized(lock)
        		{
        			jButton2ActionPerformed(evt);
        			lock.notify();
        		}
        	}
        });
        
        GroupLayout layout = new GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .addContainerGap()
                .add(layout.createParallelGroup(GroupLayout.LEADING)
                    .add(jPanel1, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .add(GroupLayout.TRAILING, layout.createSequentialGroup()
                        .add(jButton2)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(jButton1)))
                .addContainerGap())
        );
        
        layout.linkSize(new Component[] {jButton1, jButton2}, GroupLayout.HORIZONTAL);
        
        layout.setVerticalGroup(
                layout.createParallelGroup(GroupLayout.LEADING)
                .add(layout.createSequentialGroup()
                    .addContainerGap()
                    .add(jPanel1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addPreferredGap(LayoutStyle.UNRELATED)
                    .add(layout.createParallelGroup(GroupLayout.BASELINE)
                        .add(jButton1)
                        .add(jButton2))
                    .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        
        jPanel1.getAccessibleContext().setAccessibleName("Flight search");
        
        pack();
	}
	
	
	/** 
	 * Action performed regarding <code>jButton1</code> (Cancel button), namely to
	 * close the window
	 * @param Event
	 */
	private void jButton1ActionPerformed(ActionEvent evt) 
	{ System.exit(0); }
	
	
	/** 
	 * Action performed regarding <code>jButton2</code> (OK button), namely to 
	 * execute the business rules
	 * @param Event 
	 */
	private void jButton2ActionPerformed(ActionEvent evt) 
	{
		try 
		{
			this.from = (String) jComboBox1.getSelectedItem();		// Departure airport
			this.to = (String) jComboBox2.getSelectedItem();		// Arrival airport
			
			// Invalid selection (departure and arrival airports are the same)
			if (from.equals(to))
				JOptionPane.showMessageDialog(null, "The departure and arrival airports can not be the same.\n" + 
					"Please, try again.", "Error", JOptionPane.ERROR_MESSAGE);
			else
			{
				this.departure = jTextField1.getText();	// Departure date
				this.arrival = jTextField2.getText();		// Arrival date
				
				// Invalid date (empty date fields)
				if (departure.equals("") || arrival.equals(""))
				{
					JOptionPane.showMessageDialog(null, "The departure and/or arrival dates can not be empty.\n" + 
						"Please, try again.", "Error", JOptionPane.ERROR_MESSAGE);
				}
				else
				{
					// Converts a date from a String object to a Date object
					DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
					Date departureDate = formatter.parse(departure);	
					Date arrivalDate = formatter.parse(arrival);
					
					// Invalid date (arrival date is before departure date)
					if (arrivalDate.before(departureDate))
						JOptionPane.showMessageDialog(null, "The arrival date is before the departure date.\n" + 
							"Please, try again.", "Error", JOptionPane.ERROR_MESSAGE);
					else
						this.dispose();			// Closes the window after user interaction
				}
			}
		}
		catch (ParseException e) 
		{ e.printStackTrace(); }
	}
}
